using System;
using System.Text.RegularExpressions;
using RPGOnline.Controls.Chat;
using RPGOnline.Controls.Chat.Events;
using RPGOnline.Remoting;
using RPGOnline.Remoting.Entities;

namespace RPGOnline.Filters
{
    public class PrivateMessanger : IMessageHandler
    {
        private readonly ChatManager m_chatManager;
        private readonly SessionContext m_sessionContext;
        private readonly UserManager m_userManager;
        private Regex m_format = new Regex(@"^@(?<userName>[^ ]+)?(?:\ )(?<message>.+)");
        private Regex m_groupFormat = new Regex(@"^\#(?<groupName>[^ ]+)?(?:\ )(?<message>.+)");

        public event EventHandler<SendPrivateMessageEventArgs> OnSendPrivateMessage;
        public event EventHandler<SendGroupMessageEventArgs> OnSendGroupMessage;

        public User DefaultChatUser { get; set; }

        public PrivateMessanger(ChatManager chatManager, SessionContext sessionContext, UserManager userManager)
        {
            m_chatManager = chatManager;
            m_sessionContext = sessionContext;
            m_userManager = userManager;
        }

        public bool IsValid(string message)
        {
            return m_format.IsMatch(message) || m_groupFormat.IsMatch(message);
        }

        public bool Handle(string message)
        {
            return HandlePrivate(message) || HandleGroup(message);
        }

        private bool HandleGroup(string messageString)
        {
            if (!m_groupFormat.IsMatch(messageString))
                return false;

            Match match = m_groupFormat.Match(messageString);

            Group groupName = match.Groups["groupName"];
            Group message = match.Groups["message"];

            ChatGroup chatGroup = m_sessionContext.MainChatGroup;
            if(groupName.Success)
            {
                chatGroup = m_sessionContext.FindChatGroupByName(groupName.Value);
                if (chatGroup == null)
                    return false;
            }

            if (OnSendGroupMessage != null)
                OnSendGroupMessage(this, new SendGroupMessageEventArgs(m_userManager.CurrentUser, chatGroup, message.Value));

            return true;
        }

        public bool HandlePrivate(string messageString)
        {
            if (!m_format.IsMatch(messageString))
                return false;

            Match match = m_format.Match(messageString);

            Group userName = match.Groups["userName"];
            Group message = match.Groups["message"];

            User destinationUser = DefaultChatUser;
            if (userName.Success)
                destinationUser = m_sessionContext.FindUserByName(userName.Value) ?? m_sessionContext.FindByCharacterName(userName.Value); 

            if (destinationUser == null)
                return false;

            if(OnSendPrivateMessage != null)
                OnSendPrivateMessage(this, new SendPrivateMessageEventArgs(m_userManager.CurrentUser, destinationUser, message.Value));

            return true;
        }
    }
}